<?php
/**
 *	Views of Bugs.
 *	@package		tools.BugTracker
 *	@author			Christian Würker <Christian.Wuerker@CeuS-Media.de>
 *	@since			01.11.2005
 *	@version		1.0
 */
/**
 *	Views of Bugs.
 *	@package		tools.BugTracker
 *	@extends		CMF_Krypton_DefinitionView
 *	@uses			BugStatements
 *	@uses			Bug
 *	@uses			Assignment
 *	@uses			Attachment
 *	@uses			Comment
 *	@uses			User
 *	@uses			Server
 *	@uses			Project
 *	@uses			ServerProject
 *	@uses			Search
 *	@author			Christian Würker <Christian.Wuerker@CeuS-Media.de>
 *	@since			01.11.2005
 *	@version		1.0
 *	@todo			Language Support of Messages
 *	@todo			Code Documentation
 */
class View_Bug_Manager extends CMF_Krypton_Core_DefinitionView
{
	/**
	 *	Builds Content Views.
	 *	@access		public
	 *	@return		void
	 */
	public function buildContent()
	{
		$request	= $this->registry->get( 'request' );
		$auth		= $this->registry->get( 'auth' );
		$bug_id 	= $request->get( 'bug_id' );
		$content	= "";
		if( $bug_id )
		{
			$viewEdit	= new View_Bug_Manager_Edit();
			$viewAttach	= new View_Bug_Manager_Attachment();
			if( $auth->hasRight( "bug", "edit" ) )
			{
				$viewAssign	= new View_Bug_Manager_Assignment();
				$content	.= $viewEdit->buildContent();
				$content	.= $viewAttach->buildContent();
				$content	.= $viewAssign->buildContent();
				$content	.= $this->buildContentMessage();
			}
			else if( $auth->hasRight( "bug", "view" ) )
			{
				$bug	= new Bug( $bug_id );
				if( $bug->isOwner( $auth->getCurrentUser() ) )
					$content	.= $viewEdit->buildContent();
				else
				{
					$view		= new View_Bug_Manager_View;
					$content	.= $view->buildContent();
				}
				$content	.= $viewAttach->buildContent();
			}
		}
		else
		{
			$view		= new View_Bug_Manager_List;
			$content	.= $view->buildContent();
		}
		return $content;
			
	}
	
	/**
	 *	Builds Control View from Wiki File.
	 *	@access		public
	 *	@return		string
	 */
	public function buildControl()
	{
		$request	= $this->registry->get( 'request' );
		$auth		= $this->registry->get( 'auth' );

		$content	= "";
//		if ($auth->hasRight( "bugs", "list" ) )
//		{
//		}
		$content	.= $this->buildControlFilter();
		$content	.= $this->buildControlSearchs();

		return $content;	
	}

	/**
	 *	Contructs HTML Output.
	 *	@access		private
	 *	@return		string
	 *	@deprecated	Not used.
	 */
	private function buildContentEditComment()
	{
		$config		= $this->registry->get( 'config' );
		$request	= $this->registry->get( 'request' );
		$words		= $this->words['bug']['edit'];

		if( $bug_id	= $request->get( 'bug_id' ) )
		{
			$ui	= $this->buildForm( 'bug', 'addComment', 'bug', 'edit' );
			
			$ui['form']		= $this->html->Form( 'addComment', "?link=".$request->get( 'link' )."&bug_id=".$request->get( 'bug_id' ) );
			$ui['colgroup']		= $this->html->ColumnGroup( "30%", "70%" );
			$ui['caption']		= $this->html->TableCaption( $words['heading_comment'], 'edit' );
			return $this->loadTemplate( 'bug.comment', $ui );
		}
	}

	//  --  SEARCH & LIST  --  //
	/**
	 *	Contructs HTML Output.
	 *	@access		private
	 *	@return		string
	 */
	private function buildControlFilter()
	{
		$dbc		= $this->registry->get( 'dbc' );
		$config		= $this->registry->get( 'config' );
		$request	= $this->registry->get( 'request' );
		$session	= $this->registry->get( 'session' );
		$auth		= $this->registry->get( 'auth' );
		$words		= $this->words['bug']['filter'];

		//  --  FIELD ORDER --  //
		$bug	= new Model_Bug();
		$fields	= $bug->getColumns();
		$opt_order	= array( "" => $words ['order_none'] );
		foreach( $fields as $field )
			if( isset( $words['order_'.$field] ) )
				$opt_order[$field]	= $words['order_'.$field];
		if( $select = $session->get( 'bug_order' ) )
			$opt_order['_selected']	= $select;

		//  --  ORDER DIRECTION  --  //
		$opt_direction	= array( "" => $words ['order_none'] );
		$opt_direction	= array(
			 '' 		=> $words ['order_none'],
			'ASC'	=> $words['direction_asc'],
			'DESC'	=> $words['direction_desc'],
			);
		$opt_direction['_selected']	= $session->get( 'bug_direction' );

		//  --  SERVERS  --  //
		$_servers	= new Model_Server();
		$servers	= $_servers->find();
		$opt_server	= array( '' => $words['option_all'] );
		foreach( $servers as $server )
			$opt_server[$server['server_id']]	= $server['title'];
		$opt_server['_selected']	= $session->get( 'bug_server' );

		//  --  PROJECTS  --  //
		$_projects	= new Model_Project();
		$projects		= $_projects->find();
		$opt_project		= array( '' => $words['option_all'] );
		foreach( $projects as $project )
			$opt_project[$project['project_id']]	= $project['title'];
		$opt_project['_selected']	= $session->get( 'bug_project' );

		//  --  TYPES  --  //
		$opt_type		= array( '' => $words['option_all'] );
		foreach( $this->words['main']['types'] as $key => $word )
			$opt_type[$key] = $word;
		$opt_type['_selected']	= $session->get( 'bug_type' );

		//  --  PRIORITIES  --  //
		$opt_priority		= array( '' => $words['option_all'] );
		foreach( $this->words['main']['priorities'] as $key => $value )
			$opt_priority[$key] = $value;
		$opt_priority['_selected']	= $session->get( 'bug_priority' );

		//  --  STATES  --  //
		$opt_status		= array( '' => $words['option_all'] );
		foreach( $this->words['main']['states'] as $key => $word )
			$opt_status[$key] = $word;
		$opt_status['_selected']	= $session->get( 'bug_status' );
		
		//  --  USERS  --  //
		$_users		= new Model_User();
		$users		= $_users->find();
		$opt_reporter		= array( '' => $words['option_all'] );
		$opt_developer	= array( '' => $words['option_all'] );
		foreach( $users as $user )
		{
			$_user	= new Logic_User( $user['user_id'] );
#			if( $_user->hasRole( $user['user_id'], 3 ) )		//  is a Developer
#				$opt_developer[$user['user_id']]	= $user['username'];
			$opt_reporter[$user['user_id']]	= $user['username'];
		}
		$opt_developer['_selected']	= $session->get( 'bug_developer' );
		$opt_reporter['_selected']	= $session->get( 'bug_reporter' );

		//  --  SELECT SOURCES  --  //
		$sources	= array(
			'opt_server'		=> $opt_server,
			'opt_project'		=> $opt_project,
			'opt_priority'		=> $opt_priority,
			'opt_type'		=> $opt_type,
			'opt_status'		=> $opt_status,
			'opt_reporter'		=> $opt_reporter,
			'opt_developer'	=> $opt_developer,
			'opt_order'		=> $opt_order,
			'opt_direction'		=> $opt_direction,
			);
		
		$data	= array(
			'title'	=> $session->get( 'bug_title' ),
			'limit'	=> $session->get( 'bug_limit' ),
			);

		//  --  COMPONENTS   --  //
		$ui	= $this->buildForm( 'bug', 'filterBugs', 'bug', 'filter', $data, $sources );
		$button_clear		= $this->html->ResetButton( $words['button_clear'], 'butshort', "resetFormular( this.form, this )" );
		$button_reset		= $this->html->ResetButton( $words['button_reset'], 'butshort' );
		$button_filter		= $this->html->Button( 'filterBugs', $words['button_filter'], 'butshort filter' );
		$ui['field_buttons']	= $this->html->Field( '', $button_clear.$button_reset.$button_filter, '', '', 2 );
		
		//  --  PANEL TEMPLATE  --  //
		$ui['form']			= $this->html->Form( 'filterBugs', "?link=".$request->get( 'link' ) );
		$ui['colgroup']			= $this->html->ColumnGroup( "30%", "70%" );
		$ui['caption']			= $this->html->TableCaption( $words['caption'] );
		$ui['heading']			= $words['heading'];

		return $this->loadTemplate( 'bug.filter', $ui );
	}

	/**
	 *	...
	 *	@access		public
	 *	@param		...
	 *	@param		...
	 *	@return		string
	 */
	public function getIconURL( $priority, $status )
	{
		$config	= $this->registry->get( 'config' );
		$url	= $config['paths']['themes'].$config['layout']['theme']."/images/icons/priostate".$priority.$status.".png";
		return $url;

	}

	/**
	 *	...
	 *	@access		private
	 *	@return		string
	 */
	private function buildControlSearchs()
	{
		$config	= $this->registry->get( 'config' );
		$auth	= $this->registry->get( 'auth' );
		$words	= $this->words['bug']['searchs'];
		
		$search	= new Model_BugSearch();
		$search->focusIndex( 'userId', $auth->getCurrentUser() );
		$data	= $search->get( FALSE );
		$i	= 0;
		$ui['list']	= "<tr><td></td><td>".$words['no_searches']."</td></tr>";
		if( count( $data ) )
		{
			$list	= array();
			foreach( $data as $entry )
			{
				$style	= ++$i % 2 ? 'list1' : 'list2';
				$image	= $this->html->Image( $config['paths']['themes'].$config['layout']['theme']."/images/icons/cross.gif", $words['link_remove'] );
				$remove	= $this->html->Link( "?link=bug&search_id=".$entry['search_id']."&removeSearch=1", $image, 'image' );
				$link		= $this->html->Link( "?link=bug&search_id=".$entry['search_id'], $entry['title'] );
				$list[]	= "<tr class='".$style."'><td>".$remove."</td><td>".$link."</td></tr>";
			}
			$ui['list']		= implode( "\n\t", $list );
		}
		$ui['colgroup']	= $this->html->ColumnGroup( "7%", "93%" );
		$ui['caption']	= $this->html->TableCaption( $words['caption'] );
		$ui['heading']	= $words['heading'];
		return $this->loadTemplate( "bug.searches", $ui );
	}

	//  --  PRIVATE FUNCTIONS  --  //
	/**
	 *	Insert a Link to a BugEntry if pattern '@bug ?#([0-9]+)@i' is found.
	 *	@access		private
	 *	@param		string	Text to substitute in
	 *	@return		string
	 */
	private function includeBugLink( $string )
	{
		if( preg_match( "@bug ?#[0-9]@i", $string ) )
			$string	= preg_replace_callback( "@bug ?#([0-9]+)@i", array( $this, 'includeBugLink_callback' ), $string );
		return $string;
	}

	/**
	 *	Callback for BugViews::includeBugLink.
	 *	@access		private
	 *	@param		array	matches		Resulting array of matches
	 *	@return		string
	 */
	private function includeBugLink_callback( $matches )
	{
		$request	= $this->registry->get( 'request' );

		$link		= $this->html->Link( "?link=".$request->get( 'link' )."&bug_id=".$matches[1], "Bug #".$matches[1] );
		return $link;
	}

	/**
	 *	Compares unchanged to changes Bug Report and returns the differences.
	 *	@access		public
	 *	@param		array	old		Unchanged Data of Bug Report
	 *	@param		array	new		Changed Data of Bug Report
	 *	@return		array
	 *	@author		Christian W�rker <Christian.Wuerker@CeuS-Media.de>
	 *	@since		01.11.2005
	 *	@version		1.0
	 */
	private function compareInformation( $old, $new )
	{
		$changes	= array();
		$keys	= array_keys( array_merge( $old, $new ) );
		foreach( $keys as $key )
			if( isset( $new[$key] ) )
				if( $old[$key] !== $new[$key] )
					$changes[]	= $key;
		return $changes;
	}

	/**
	 *	Build Output of Bug Report for eMail.
	 *	@access		public
	 *	@param		array	old		Data of Bug Report
	 *	@param		array	new		Unchanged Data of Bug Report
	 *	@return		string
	 *	@author		Christian W�rker <Christian.Wuerker@CeuS-Media.de>
	 *	@since		01.11.2005
	 *	@version		1.0
	 */
	public function buildInformationBlock( $data, $old_data = false )
	{
		$config		= $this->registry->get( 'config' );
		$words		= $this->registry->get( 'words' );

		$changes		= ( false !== $old_data ) ? $this->compareInformation( $data, $old_data ) : array();
		$changed	= array();
		$keys		= array_keys( $data );
		foreach( $keys as $key )
			$ui['changed'][$key]	= ( in_array( $key,	$changes ) ) ? "x" : " ";

		$server		= new Server( $data['server'] );
		$project	= new Project( $data['project'] );
		$user		= new User( $data['author'] );
		$server		= $server->getData( TRUE );
		$project	= $project->getData( TRUE );
		$user		= $user->getData( TRUE );

		$data	= array(
			"bug_id"		=> $data['bug_id'],
			"server"		=> $server['title'],
			"project"		=> $project['title'],
			"location"		=> $data['location'],
			"function"		=> $data['function'],
			"type"			=> $words['main']['types'][$data['type']],
			"priority"		=> $words['main']['priorities'][$data['priority']],
			"status"		=> $words['main']['states'][$data['status']],
			"author"		=> $user['username'],
			"title"			=> $data['title'],
			"description"	=> $data['description'],
		);

		$comment	= new Comment();
		$comment->focusForeign( "bug_id", $data['bug_id'] );
		$comments	= $comment->getData( false );
		$list			= array();
		foreach( $comments as $comment )
		{
			$user	= new User( $comment['author'] );
			$user	= $user->getData( TRUE );
			$list[]	= "[".date( $config['layout']['format_timestamp'], $comment['timestamp'] )."] ".$user['username']."\n".$comment['comment'];
		}
		$ui['words']	= $words;
		$ui['data']		= $data;
		$ui['comments']	= implode( "\n", $list );

		return $this->loadTemplate( "BugInformation", $ui );
	}
}
?>
